﻿using bfs.sms.sdmx.util.Variable;
using CarlosAg.ExcelXmlWriter;
using Ch.Admin.Bfs.Sms.Sdmx.Extension.CodeBook.Meta;
using SdmxMl.Structure;
using System.Collections.Generic;


namespace bfs.sms.sdmx.util.Excel
{
    /// <summary>
    /// Class for generating catalog of codelists
    /// </summary>
    public class ExcelCodelists : ExcelBasicCatalog
    {
         #region Internal members

        /// <summary>List of codelists part of the book </summary>
        Dictionary<string, CodeListType> dicoCodelists;

        /// <summary>
        /// Special codelist (optional) resuming all quality codes
        /// </summary>
        CodeListType qualityCodelist;

        #endregion

        #region C'tor

        public ExcelCodelists(string author, string company, CodeListType cltQuality)
            : base(author, company)
        {
            qualityCodelist = cltQuality;
        }

        #endregion

        #region Generation

        /// <summary> Excel XML Workbook generation </summary>
        /// <param name="varSheets"></param>
        /// <param name="lang">language code to use</param>
        public override void Generate(List<VariableSheet> varSheets, string lang, VarCatalogOptions options)
        {
            langCd = lang;
            catalogOptions = options;

            CreateTableOfContent();

            //Establish dictionary of codelists used in variables catalog
            dicoCodelists = new Dictionary<string, CodeListType>(32);
            foreach (VariableSheet vs in varSheets)
            {
                foreach (Variable.Variable var in vs.VarList)
                {
               //     CodeListType clt = var.GetCodelistAndQuality();
                    CodeListType clt = var.Codelist;
                    if (clt != null)
                    {
                        if (dicoCodelists.ContainsKey(clt.FullIdent) == false)
                        {
                            dicoCodelists.Add(clt.FullIdent, clt);
                            GenerateWorksheet(var.CodeSheetId, clt);
                        }
                    }
                }
            }

            // A Quality list resume exists
            if (qualityCodelist != null)
                GenerateWorksheet(QualitySheetId, qualityCodelist);

            FillTableOfContents();

        }

        /// <summary> Generates a Excel Worksheet representing a codelist </summary>
        /// <param name="id">Worksheet id name</param>
        /// <param name="clt">sdmx codelist</param>
        protected void GenerateWorksheet(string id, CodeListType clt)
        {
            int headerRowCount = 3;
            tocSet.Add(new TableOfContentInfo(id,  clt.Name.GetForLanguage(langCd)));

            // Determine sheet columns poroperties
            sheet = book.Worksheets.Add(id);
            sheet.Table.DefaultColumnWidth = 70F;
            sheet.Table.ExpandedColumnCount = 2;
            sheet.Table.ExpandedRowCount = clt.CodeList.Count + headerRowCount;
            sheet.Table.FullColumns = 1;
            sheet.Table.FullRows = 1;

            // Lock top rows
            SplitSheetHorizontal(sheet, 3);

            // Columns code override size
            WorksheetColumn columnVar = sheet.Table.Columns.Add();
            columnVar.Index = 1;
            columnVar.Width = catalogOptions.CodeIdPixels;

            // Columns formats  override size
            columnVar = sheet.Table.Columns.Add();
            columnVar.Index = 2;
            columnVar.Width = catalogOptions.CodeNamePixels;

            // Place header
            List<string> header = new List<string>(new string[] { "Code", "Text" });
            // Filtering range
            bool hasFilter = false;

            if (hasFilter)
                CreateNamedRange(sheet, 3, clt.CodeList.Count, header.Count);

            AddHeaderInfo(clt.FullIdent, clt.Name.GetForLanguage(langCd),  clt.Description.GetForLanguage(langCd), header, hasFilter);

            // Now all codes
            this.SetNumericCell = clt.GetDefaultTextFormat().IsNumeric;
            foreach (CodeType code in clt.CodeList)
            {
                FillRow(code);
            }
        }

        /// <summary> Fill a row with code information </summary>
        /// <param name="code">the code information</param>
        protected void FillRow(CodeType code)
        {
            WorksheetRow row = sheet.Table.Rows.Add();
            AddCell(row, code.Id, true);
            AddCell(row, code.Name.GetForLanguage(langCd), true);
        }

        #endregion
    }
}
